package com.carnation.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.carnation.bean.GroupMenu;
import com.carnation.bean.HeadMenu;
import com.carnation.bean.Menu;
import com.carnation.bean.MenuTree;

public class MenuRead {
	Logger logger = Logger.getLogger(MenuRead.class);
	Document document;
	SAXReader reader;
	String fileName = "Menu.xml";
	
	public MenuRead(){
		if(!checkFile()){
			logger.error("菜单配置文件不存在");
			System.exit(0);
		}
		else{
			try{
				reader = new SAXReader();
				String file = MenuRead.class.getClassLoader().getResource("").getPath() + fileName;
				logger.debug(file);
				reader.setEncoding("UTF-8");
				document = reader.read(new File(file));	
			}
			catch(Exception e){
				logger.error("读取菜单文件失败",e);
			}
		}
	}
	
	private boolean checkFile(){
		String file = MenuRead.class.getClassLoader().getResource("").getPath() + fileName;
		File  files = new File(file);
		if(files.exists()){
			return true;
		}
		else{
			return false;
		}
	}
	
	@SuppressWarnings("rawtypes")
	public List<HeadMenu> getHeadMenuList(){
		List<HeadMenu> list = new ArrayList<HeadMenu>();
		Element root = document.getRootElement();
		Iterator headlist = root.elements("head").iterator();
		while(headlist.hasNext()){
			Element head = (Element)headlist.next();
			String id = head.attributeValue("id");
			String name = head.attributeValue("name");
			String title = head.attributeValue("title");
			String text = head.attributeValue("text");
			String icon = head.attributeValue("icon");
			HeadMenu headMenu =  new HeadMenu(id,name, title, text,icon);
			list.add(headMenu);
		}
		return list;
	}
	
	@SuppressWarnings("rawtypes")
	public List<GroupMenu> getGroupMenuByHeadName(String headName){
		List<GroupMenu> list = new ArrayList<GroupMenu>();
		Element root = document.getRootElement();
		Iterator heads = root.elementIterator("head");
		while(heads.hasNext()){
			Element e = (Element)heads.next();
			if(e.attributeValue("name").equals(headName)){
				Iterator groups = e.elementIterator("group");
				while(groups.hasNext()){
					Element group = (Element)groups.next();
					String gId = group.attributeValue("id");
					String gName = group.attributeValue("name");
					String gIcon = group.attributeValue("icon");
					GroupMenu groupMenu = new GroupMenu(gId, gName, gIcon);
					Iterator menus = group.elementIterator("menu");
					while(menus.hasNext()){
						Element m = (Element)menus.next();
						String mId = m.attributeValue("id");
						String mName = m.attributeValue("name");
						String mIcon = m.attributeValue("icon");
						String mUrl = m.attributeValue("url");
						Menu menu = new Menu(mId, mName, mIcon, mUrl);
						groupMenu.addMenu(menu);
					}
					list.add(groupMenu);
				}
				break;
			}
		}
		return list;
	}
	
	@SuppressWarnings("rawtypes")
	public HeadMenu getHeadMenuById(String id){
		Iterator headMenus = document.selectNodes("/root/head").iterator();
		HeadMenu target = null;
		while(headMenus.hasNext()){
			Element e = (Element)headMenus.next();
			if(id.equals(e.attributeValue("id"))){
				String name = e.attributeValue("name");
				String title = e.attributeValue("title");
				String text = e.attributeValue("text");
				String icon = e.attributeValue("icon");
				target = new HeadMenu(id, name, title, text,icon);
				break;
			}
		}
		return target;
	}
	
	@SuppressWarnings("rawtypes")
	public GroupMenu getGroupMenuById(String id){
		Iterator groupMenus = document.selectNodes("/root/head/group").iterator();
		GroupMenu target = null;
		while(groupMenus.hasNext()){
			Element e = (Element)groupMenus.next();
			if(id.equals(e.attributeValue("id"))){
				String name = e.attributeValue("name");
				String icon = e.attributeValue("icon");
				target = new GroupMenu(id, name, icon);
				break;
			}
		}
		return target;
	}
	
	@SuppressWarnings("rawtypes")
	public Menu getMenuById(String id){
		Iterator menus = document.selectNodes("/root/head/group/menu").iterator();
		Menu target = null;
		while(menus.hasNext()){
			Element e = (Element)menus.next();
			if(id.equals(e.attributeValue("id"))){
				String name = e.attributeValue("name");
				String icon = e.attributeValue("icon");
				String url = e.attributeValue("url");
				target = new Menu(id, name, icon, url);
				break;
			}
		}
		return target;
	}
	/**
	 * 检查除了id节点外在兄弟节点中是否存在重复名称
	 * @param headName
	 * @param id
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public boolean checkHeadNameExists(String headName,String id){
		Iterator heads = document.selectNodes("/root/head").iterator();
		while(heads.hasNext()){
			Element e = (Element)heads.next();
			if(headName.equals(e.attributeValue("name"))&& !id.equals(e.attributeValue("id")) ){
				return true;
			}
		}
		return false;
	}
	
	
	@SuppressWarnings("rawtypes")
	public boolean checkHeadNameExists(String headName){
		Iterator heads = document.selectNodes("/root/head").iterator();
		while(heads.hasNext()){
			Element e = (Element)heads.next();
			if(headName.equals(e.attributeValue("name"))){
				return true;
			}
		}
		return false;
	}
	
	@SuppressWarnings("rawtypes")
	public boolean  checkGroupNameExists(String parentId,String groupName,String id){
		Element head = (Element)document.selectSingleNode("/root/head[@id='" + parentId + "']");
		if(head == null){
			logger.error("找不到父节点");
			return true;
		}
		Iterator groups = head.elementIterator("group");
		while(groups.hasNext()){
			Element e= (Element) groups.next();
			if(groupName.equals(e.attributeValue("name"))&&!e.attributeValue("id").equals(id) ){
				return true;
			}
		}
		return false;
	}
	@SuppressWarnings("rawtypes")
	public boolean checkGroupNameExists(String parentId,String groupName){
		Element head = (Element)document.selectSingleNode("/root/head[@id='" + parentId + "']");
		if(head == null){
			logger.error("找不到父节点");
			return true;
		}
		Iterator groups = head.elementIterator("group");
		while(groups.hasNext()){
			Element e= (Element) groups.next();
			if(groupName.equals(e.attributeValue("name"))){
				return true;
			}
		}
		return false;
	}
	
	public String getParentIdByIdAndType(String id,String type){
		String xpath=null;
		if(type.equals("group")){
			xpath = "/root/head/group[@id='" + id + "']";
		}
		else if(type.equals("menu")){
			xpath = "/root/head/group/menu[@id='" + id + "']";
		}
		else{
			xpath = null;
		}
		if(xpath == null){
			return null;
		}
		else{
			Element targert = (Element)document.selectSingleNode(xpath);
			if(targert == null){
				return null;
			}
			else{
				return targert.getParent().attributeValue("id");
			}
		}
	}
	
	@SuppressWarnings("rawtypes")
	public boolean checkMenueNameExists(String parentId,String menuName,String id){
		Element group = (Element)document.selectSingleNode("/root/head/group[@id='" + parentId + "']");
		if(group == null){
			logger.error("找不到父节点");
			return true;
		}
		Iterator menus = group.elementIterator("menu");
		while(menus.hasNext()){
			Element e = (Element)menus.next();
			if(menuName.equals(e.attributeValue("name")) && !id.equals(e.attributeValue("id"))){
				return true;
			}
		}
		return false;
	}
	
	@SuppressWarnings("rawtypes")
	public boolean checkMenueNameExists(String parentId,String menuName){
		Element group = (Element)document.selectSingleNode("/root/head/group[@id='" + parentId + "']");
		if(group == null){
			logger.error("找不到父节点");
			return true;
		}
		Iterator menus = group.elementIterator("menu");
		while(menus.hasNext()){
			Element e = (Element)menus.next();
			if(menuName.equals(e.attributeValue("name"))){
				return true;
			}
		}
		return false;
	}
	
	@SuppressWarnings("rawtypes")
	public MenuTree getMenuTree(){
		Element root = document.getRootElement();
		MenuTree rootTree = new MenuTree();
		rootTree.setId(0L);
		rootTree.setText("root");
		rootTree.setIconCls("icon-root");
		Map<Object,Object> rootMap = new HashMap<Object,Object>();
		rootMap.put("url", "/Redirect?type=root&id=" + rootTree.getId());
		rootTree.setAttributes(rootMap);
		List<MenuTree> childrenRoot = new ArrayList<MenuTree>();
		Iterator heads = root.elementIterator("head");
		while(heads.hasNext()){
			Element head = (Element)heads.next();
			MenuTree headTree = new MenuTree();
			headTree.setId(Long.valueOf(head.attributeValue("id")));
			headTree.setText(head.attributeValue("name"));
			headTree.setIconCls(head.attributeValue("icon"));
			Map<Object,Object> headMap = new HashMap<Object,Object>();
			headMap.put("url", "/Redirect?type=head&id="+headTree.getId());
			headTree.setAttributes(headMap);
			List<MenuTree> childrenHead = new ArrayList<MenuTree>();
			Iterator groups = head.elementIterator("group");
			while(groups.hasNext()){
				Element group = (Element)groups.next();
				MenuTree groupTree = new MenuTree();
				groupTree.setId(Long.valueOf(group.attributeValue("id")));
				groupTree.setText(group.attributeValue("name"));
				groupTree.setIconCls(group.attributeValue("icon"));
				Map<Object, Object> groupMap = new HashMap<Object, Object>();
				groupMap.put("url", "/Redirect?type=group&id=" + groupTree.getId());
				groupTree.setAttributes(groupMap);
				List<MenuTree> childrenGroup = new ArrayList<MenuTree>();
				Iterator menus = group.elementIterator("menu");
				while(menus.hasNext()){
					Element menu = (Element)menus.next();
					MenuTree menuTree = new MenuTree();
					menuTree.setId(Long.valueOf(menu.attributeValue("id")));
					menuTree.setText(menu.attributeValue("name"));
					menuTree.setIconCls(menu.attributeValue("icon"));
					Map<Object, Object> menuMap = new HashMap<Object,Object>();
					menuMap.put("url","/Redirect?type=menu&id=" + menuTree.getId());
					menuTree.setAttributes(menuMap);
					childrenGroup.add(menuTree);
				}
				groupTree.setChildren(childrenGroup);
				childrenHead.add(groupTree);
			}
			headTree.setChildren(childrenHead);;
			childrenRoot.add(headTree);
		}
		rootTree.setChildren(childrenRoot);
		return rootTree;
	}
}
